package com.matrix.framework.sysconfig.iplist.service;

import com.matrix.framework.sysconfig.iplist.data.IpSecurityRulePo;
import com.matrix.framework.sysconfig.iplist.data.IpSecurityRuleDto;
import com.matrix.framework.sysconfig.iplist.data.IpAccessRecordPo;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;

import java.util.Map;

/**
 * IP安全服务接口
 *
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2024/12/1 15:30
 * @Since 1.2
 */
public interface IpSecurityService {

    /**
     * 验证IP访问权限
     * @param ipAddress IP地址
     * @param username 用户名（可选）
     * @param apiPath API路径
     * @return 验证结果
     */
    Mono<IpValidationResult> validateIpAccess(String ipAddress, String username, String apiPath);

    /**
     * 记录IP访问
     * @param record 访问记录
     * @return 记录结果
     */
    Mono<Void> recordIpAccess(IpAccessRecordPo record);

    /**
     * 检查IP访问频率
     * @param ipAddress IP地址
     * @param username 用户名（可选）
     * @param apiPath API路径
     * @return 频率检查结果
     */
    Mono<RateLimitResult> checkRateLimit(String ipAddress, String username, String apiPath);

    /**
     * 保存IP安全规则
     * @param rule 安全规则
     * @return 保存结果
     */
    Mono<IpSecurityRulePo> saveRule(IpSecurityRulePo rule);

    /**
     * 删除IP安全规则
     * @param id 规则ID
     * @return 删除结果
     */
    Mono<Void> deleteRule(Long id);

    /**
     * 获取所有IP安全规则
     * @return 规则列表
     */
    Flux<IpSecurityRulePo> getAllRules();

    /**
     * 分页查询IP安全规则
     * @param dto 查询条件及分页参数
     * @return 分页结果
     */
    Mono<IpSecurityRuleDto> findRules(IpSecurityRuleDto dto);

    /**
     * 获取IP访问统计
     * @param ipAddress IP地址
     * @param days 统计天数
     * @return 统计数据
     */
    Mono<Map<String, Object>> getIpStatistics(String ipAddress, int days);

    /**
     * 清理过期的访问记录
     * @param days 保留天数
     * @return 清理结果
     */
    Mono<Long> cleanExpiredRecords(int days);

    /**
     * IP验证结果
     */
    class IpValidationResult {
        private boolean allowed;
        private String reason;
        private String action;
        private IpSecurityRulePo matchedRule;

        public IpValidationResult(boolean allowed, String reason, String action, IpSecurityRulePo matchedRule) {
            this.allowed = allowed;
            this.reason = reason;
            this.action = action;
            this.matchedRule = matchedRule;
        }

        // Getters and Setters
        public boolean isAllowed() {
            return allowed;
        }

        public void setAllowed(boolean allowed) {
            this.allowed = allowed;
        }

        public String getReason() {
            return reason;
        }

        public void setReason(String reason) {
            this.reason = reason;
        }

        public String getAction() {
            return action;
        }

        public void setAction(String action) {
            this.action = action;
        }

        public IpSecurityRulePo getMatchedRule() {
            return matchedRule;
        }

        public void setMatchedRule(IpSecurityRulePo matchedRule) {
            this.matchedRule = matchedRule;
        }
    }

    /**
     * 频率限制结果
     */
    class RateLimitResult {
        private boolean allowed;
        private String reason;
        private int remainingRequests;
        private long resetTime;

        public RateLimitResult(boolean allowed, String reason, int remainingRequests, long resetTime) {
            this.allowed = allowed;
            this.reason = reason;
            this.remainingRequests = remainingRequests;
            this.resetTime = resetTime;
        }

        // Getters and Setters
        public boolean isAllowed() {
            return allowed;
        }

        public void setAllowed(boolean allowed) {
            this.allowed = allowed;
        }

        public String getReason() {
            return reason;
        }

        public void setReason(String reason) {
            this.reason = reason;
        }

        public int getRemainingRequests() {
            return remainingRequests;
        }

        public void setRemainingRequests(int remainingRequests) {
            this.remainingRequests = remainingRequests;
        }

        public long getResetTime() {
            return resetTime;
        }

        public void setResetTime(long resetTime) {
            this.resetTime = resetTime;
        }
    }
} 